import type { Router, RouteRecordRaw } from 'vue-router';

import { usePermissionStoreWithOut } from '/@/store/modules/permission';

import { PageEnum } from '/@/enums/pageEnum';
import { useUserStoreWithOut } from '/@/store/modules/user';

import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';

import { RootRoute } from '/@/router/routes';

import { useI18n } from '/@/hooks/web/useI18n';
import { useMessage } from '/@/hooks/web/useMessage';
import { useGlobSetting } from '/@/hooks/setting';
import { h } from 'vue';

const LOGIN_PATH = PageEnum.BASE_LOGIN;

const ROOT_PATH = RootRoute.path;
const { createMessage } = useMessage();
/**
 * 白名单路径集合，在此集合中的路径不需要登录可以直接访问；目前白名单仅有用户登录路由
 */
const whitePathList: PageEnum[] = [LOGIN_PATH];
//获取env文件中配置的项目编码
const { globalProjectCode } = useGlobSetting();

export function createPermissionGuard(router: Router) {
  const userStore = useUserStoreWithOut();
  const permissionStore = usePermissionStoreWithOut();
  router.beforeEach(async (to, from, next) => {
    /*
    * 路由跳转前的判断顺序及处理
    * 0.判断如果to为用户登录，在token已经有值时跳转到登录成功后处理（不重复跳转到登录路由）
    * 1.如果to路由本身不需要访问权限控制，继续访问to路由
    * 2.如果env项目编码判定为cms系统，to路由为网站前端首页，跳转至网站前端首页（不需要访问权限控制的路由地址）
    * 3.如果from为根目录、to为默认首页路由，homePath有值并且不是默认首页路由，跳转至homePath
    * 4.如果to路由在白名单路由中(不为用户登录路由)：不管是否有token继续访问to
    * 5.判定为均需要token才能访问，如果没有token跳转到登录
    */
    console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach router:', router);
    console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach whitePathList:', whitePathList);
    console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach from:', from);
    console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach to:', to);
    console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach userStore.getUserInfo.homePath:', userStore.getUserInfo.homePath);
    //获取用户token以便与后面判断是否需要用户登录
    const token = userStore.getToken;
    console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach token=', token);
    //判断顺序及处理 0.判断如果to为用户登录，在token已经有值时跳转到登录成功后处理（不重复跳转到登录路由）
    //此处必须要加上token判断，否则此处不会进行路由跳转，导致继续往下执行到判断token为空中陷入死循环
    if (to.path === LOGIN_PATH && token) {
      console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach 判断结果：to路由为登录地址，token已有值，跳转到登录后处理方法');
      const isSessionTimeout = userStore.getSessionTimeout;
      try {
        await userStore.afterLoginAction();
        return;
        // if (!isSessionTimeout) {
        //   next((to.query?.redirect as string) || '/');
        //   return;
        // }
      } catch { }
    }
    //判断顺序及处理 1.如果to路由本身不需要访问权限控制，继续访问to路由
    //如果跳转to的meta中不需要身份验证信息，不管是否有token均进行直接跳转
    // You can access without permission. You need to set the routing meta.ignoreAuth to true
    if (to.meta.ignoreAuth) {
      console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach 判断结果：to路由在无需权限验证路由集合中，跳转到to路由');
      next();
      return;
    }
    //判断顺序及处理 2.如果env项目编码判定为cms系统，to路由为网站前端首页，跳转至网站前端首页（不需要访问权限控制的路由地址）
    //2025-5-15，实测在浏览器地址栏中输入/cms和/cms/对应的跳转判断处理不同：/cms能在basicRoutes匹配到对应路由，/cms/无法进行匹配
    //根据项目编码判定为是否为cms系统，如果为cms系统时，to为/home/index、/cms/等均跳转到basicRoutes中的路由/cms
    if (globalProjectCode === 'qckj' || globalProjectCode === 'cms' || globalProjectCode === 'yzh' || globalProjectCode === 'ky') {
      //判断如果to为/home/index时，根据项目编码判断是否进行后续的用户token的判断；如果是cms系统不需要跳转到登录，将跳转路由指定为/cms
      if (to.path === '/'
        || to.path === '/home/index' || to.path === '/home/index/'
        || to.path === '/home' || to.path === '/home/'
        || to.path === '/index' || to.path === '/index/'
        || to.path === '/cms' || to.path === '/cms/') {
        //由于跳转到/home/index也需要用户token，因此在此单独进行处理；对cms系统固定跳转至网站首页
        console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach 判断结果：当前项目为cms系统，to路由判定为网站前端首页，跳转到/cms');
        next('/cms');
        return;
      }
    }
    //判断顺序及处理 3.如果from为根目录、to为默认首页路由，homePath有值并且不是默认首页路由，跳转至homePath
    //此处判断from为根路由、to为/home/index、homePath有值并且不是/home/index：满足以上情况时跳转到homePath
    if (
      from.path === ROOT_PATH &&
      to.path === PageEnum.HOME &&
      userStore.getUserInfo.homePath &&
      userStore.getUserInfo.homePath !== PageEnum.HOME
    ) {
      console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach 判断结果：跳转到userStore.getUserInfo.homePath');
      next(userStore.getUserInfo.homePath);
      return;
    }

    //判断顺序及处理 4.如果to路由在白名单路由中(用户登录路由)：如已有token跳转到登录后处理，如没有token继续访问to（进行用户登录操作）
    // Whitelist can be directly entered
    //如果请求的目标在白名单中，可以直接进行路由跳转
    if (whitePathList.includes(to.path as PageEnum)) {
      //在白名单中的目标路由，不需要判断是否有token信息
      console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach 判断结果：to路由在白名单路由集合中，跳转到to路由');
      next();
      return;
    }

    // token does not exist
    //如果token为空，不存在token，跳转至登录的路由地址
    if (!token) {
      console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach 判断结果：token为空，to路由需要用户token才能访问，跳转到登录路由');
      //界面中显示提示信息
      const { t } = useI18n();
      createMessage.info({
        content: () => h('span', t('sys.uac.notExistTokenMessage')),
        duration: 5,
      });
      //跳转到登录路由地址，指定登录后的跳转路由为toto.path
      const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
        path: LOGIN_PATH,
        replace: true,
      };
      if (to.path) {
        redirectData.query = {
          ...redirectData.query,
          redirect: to.path,
        };
      }
      next(redirectData);
      return;
    }

    // Jump to the 404 page after processing the login
    if (
      from.path === LOGIN_PATH &&
      to.name === PAGE_NOT_FOUND_ROUTE.name &&
      to.fullPath !== (userStore.getUserInfo.homePath || PageEnum.HOME)
    ) {
      next(userStore.getUserInfo.homePath || PageEnum.HOME);
      return;
    }

    // get userinfo while last fetch time is empty
    if (userStore.getLastUpdateTime === 0) {
      try {
        const userInfo = await userStore.getUserInfoAction();
        console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach userStore.getUserInfoAction()', userInfo);
        //如果根据token获取到的用户信息为null，界面中显示提示信息
        if (userInfo === undefined || userInfo === null) {
          const { t } = useI18n();
          createMessage.error({
            content: () => h('span', t('sys.uac.tokenInvalidMessage')),
            duration: 5,
          });
          //跳转到登录路由地址，指定登录后的跳转路由为toto.path
          const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
            path: LOGIN_PATH,
            replace: true,
          };
          if (to.path) {
            redirectData.query = {
              ...redirectData.query,
              redirect: to.path,
            };
          }
          next(redirectData);
          return;
        }
      } catch (err) {
        console.log('src\\router\\guard\\permissionGuard.ts createPermissionGuard beforeEach userStore.getUserInfoAction() error', err);
        next();
        return;
      }
    }
    if (permissionStore.getIsDynamicAddedRoute) {
      next();
      return;
    }

    const routes = await permissionStore.buildRoutesAction();

    routes.forEach((route) => {
      router.addRoute(route as unknown as RouteRecordRaw);
    });

    router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);

    permissionStore.setDynamicAddedRoute(true);

    if (to.name === PAGE_NOT_FOUND_ROUTE.name) {
      // 动态添加路由后，此处应当重定向到fullPath，否则会加载404页面内容
      next({ path: to.fullPath, replace: true, query: to.query });
    } else {
      const redirectPath = (from.query.redirect || to.path) as string;
      const redirect = decodeURIComponent(redirectPath);
      const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
      next(nextData);
    }
  });
}
